#
# Copyright (C) [2024] Xingyun Integrated Circuit, Inc.
#
# GreenCode was a private technology asset of Xingyun Integrated Circuit， Inc （Confidential）
# Author: Shawn.Tan
# Date: 2025.10.28
#
# History: Initial Version 2025.10.28
#
#
from VectorTestSequence import VectorTestSequence
from base.ChoicesModifier import ChoicesModifier
from gpgpu.EnvGPGPU import EnvGPGPU
from gpgpu.GenThreadGPGPU import GenThreadGPGPU


#  This test verifies that vector register operands with different layouts
#  don't overlap.
class MainSequence(VectorTestSequence):
    def __init__(self, aGenThread, aName=None):
        super().__init__(aGenThread, aName)

        self._mInstrList = (
            "VNCLIP.WI##CALM",
            "VNCLIP.WV##CALM",
            "VNCLIP.WX##CALM",
            "VNCLIPU.WI##CALM",
            "VNCLIPU.WV##CALM",
            "VNCLIPU.WX##CALM",
            "VNSRA.WI##CALM",
            "VNSRA.WV##CALM",
            "VNSRA.WX##CALM",
            "VNSRL.WI##CALM",
            "VNSRL.WV##CALM",
            "VNSRL.WX##CALM",
            "VWADD.VV##CALM",
            "VWADD.VX##CALM",
            "VWADD.WV##CALM",
            "VWADD.WX##CALM",
            "VWADDU.VV##CALM",
            "VWADDU.VX##CALM",
            "VWADDU.WV##CALM",
            "VWADDU.WX##CALM",
            "VWMACC.VV##CALM",
            "VWMACC.VX##CALM",
            "VWMACCSU.VV##CALM",
            "VWMACCSU.VX##CALM",
            "VWMACCU.VV##CALM",
            "VWMACCU.VX##CALM",
            "VWMACCUS.VX##CALM",
            "VWMUL.VV##CALM",
            "VWMUL.VX##CALM",
            "VWMULSU.VV##CALM",
            "VWMULSU.VX##CALM",
            "VWMULU.VV##CALM",
            "VWMULU.VX##CALM",
            "VWSUB.VV##CALM",
            "VWSUB.VX##CALM",
            "VWSUB.WV##CALM",
            "VWSUB.WX##CALM",
            "VWSUBU.VV##CALM",
            "VWSUBU.VX##CALM",
            "VWSUBU.WV##CALM",
            "VWSUBU.WX##CALM",
        )

    # Set up the environment prior to generating the test instructions.
    def _setUpTest(self):
        choices_mod = ChoicesModifier(self.genThread)

        vsew_choice_weights = {
            "0x0": 10,
            "0x1": 10,
            "0x2": 10,
            "0x3": 0,
            "0x4": 0,
            "0x5": 0,
            "0x6": 0,
            "0x7": 0,
        }
        choices_mod.modifyRegisterFieldValueChoices("vtype.VSEW", vsew_choice_weights)

        # Ensure vector register group size is no more than 4, as larger values
        # are not legal for widening and narrowing instructions
        vlmul_choice_weights = {
            "0x0": 10,
            "0x1": 10,
            "0x2": 10,
            "0x3": 0,
            "0x4": 0,
            "0x5": 10,
            "0x6": 10,
            "0x7": 10,
        }
        choices_mod.modifyRegisterFieldValueChoices("vtype.VLMUL", vlmul_choice_weights)

        choices_mod.commitSet()

    # Return the maximum number of test instructions to generate.
    def _getMaxInstructionCount(self):
        return 1000

    # Return a list of test instructions to randomly choose from.
    def _getInstructionList(self):
        return self._mInstrList

    # Verify additional aspects of the instruction generation and execution.
    #
    #  @param aInstr The name of the instruction.
    #  @param aInstrRecord A record of the generated instruction.
    def _performAdditionalVerification(self, aInstr, aInstrRecord):
        vd_val = aInstrRecord["Dests"]["vd"]
        vs1_val = aInstrRecord["Srcs"].get("vs1")
        vs2_val = aInstrRecord["Srcs"]["vs2"]
        if aInstr.startswith("VW"):
            if vs1_val:
                self.assertNoRegisterOverlap(aInstr, vd_val, vs1_val, aRegCountMultipleA=2)

            if ".W" not in aInstr:
                self.assertNoRegisterOverlap(aInstr, vd_val, vs2_val, aRegCountMultipleA=2)
        elif aInstr.startswith("VN"):
            self.assertNoRegisterOverlap(aInstr, vd_val, vs2_val, aRegCountMultipleB=2)
        else:
            self.error("Unexpected instruction %s" % aInstr)


MainSequenceClass = MainSequence
GenThreadClass = GenThreadGPGPU
EnvClass = EnvGPGPU
